package com.apache.client.common;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.apache.tools.ConfigUtil;
import com.apache.tools.StrUtil;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created on 17/6/7.
 * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类，直接通过
 * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
 * 工程依赖了2个jar包(存放在工程的libs目录下)
 * 1:aliyun-java-sdk-core.jar
 * 2:aliyun-java-sdk-dysmsapi.jar
 *
 * 备注:Demo工程编码采用UTF-8
 * 国际短信发送请勿参照此DEMO
 */
public class SmsUtil {
    private static Logger log = Logger.getLogger(SmsUtil.class);
    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";
    private static final String file_Config = "config.properties";//系统配置文件

    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
    static String sms_code_start = "F";
    static String sms_aliyun_accessKeyId = "";
    static String sms_aliyun_accessKeySecret = "";
    static String sms_aliyun_signName = "";//IUS快速开发平台
    static String sms_aliyun_templateCode = "";


    static {
        sms_code_start = ConfigUtil.getInstance().getLocalByKey(file_Config,"sms_code_start");
        sms_aliyun_accessKeyId = ConfigUtil.getInstance().getLocalByKey(file_Config,"sms_aliyun_accessKeyId");
        sms_aliyun_accessKeySecret = ConfigUtil.getInstance().getLocalByKey(file_Config,"sms_aliyun_accessKeySecret");
        sms_aliyun_signName = ConfigUtil.getInstance().getLocalByKey(file_Config,"sms_aliyun_signName");
        sms_aliyun_templateCode = ConfigUtil.getInstance().getLocalByKey(file_Config,"sms_aliyun_templateCode");
    }

    /**
     * 发送短信验证码
     * 所有参数：包括手机号，验证码，及阿里云配置信息（由调用方自行传入）
     * @return
     */
    public static Map<String,String> sendSms(Map<String,String> param){
        log.info("send sms param->"+param);
        return sendTo(param);
    }

    /**
     * 发送短信验证码
     * @param mobile 手机号
     * @param codeNo 验证码（纯数字）
     * @return
     */
    public static Map<String,String> sendSms(String mobile,String codeNo){
        if(StrUtil.isNull(sms_code_start)){
            log.error(file_Config+"中缺少[sms_code_start]配置信息");
            return getResultMap("","","fail","缺少配置参数");
        }
        if(StrUtil.isNull(sms_aliyun_accessKeyId)){
            log.error(file_Config+"中缺少[sms_aliyun_accessKeyId]配置信息");
            return getResultMap("","","fail","缺少配置参数");
        }
        if(StrUtil.isNull(sms_aliyun_accessKeySecret)){
            log.error(file_Config+"中缺少[sms_aliyun_accessKeySecret]配置信息");
            return getResultMap("","","fail","缺少配置参数");
        }
        if(StrUtil.isNull(sms_aliyun_signName)){
            log.error(file_Config+"中缺少[sms_aliyun_signName]配置信息");
            return getResultMap("","","fail","缺少配置参数");
        }
        if(StrUtil.isNull(sms_aliyun_templateCode)){
            log.error(file_Config+"中缺少[sms_aliyun_templateCode]配置信息");
            return getResultMap("","","fail","缺少配置参数");
        }
        Map<String,String> param = new HashMap<>();
        param.put("sms_code_start",sms_code_start);
        param.put("sms_aliyun_accessKeyId",sms_aliyun_accessKeyId);
        param.put("sms_aliyun_accessKeySecret",sms_aliyun_accessKeySecret);
        param.put("sms_aliyun_signName",sms_aliyun_signName);
        param.put("sms_aliyun_templateCode",sms_aliyun_templateCode);
        param.put("mobile",mobile);
        param.put("codeNo",codeNo);

        return sendTo(param);

    }
    private static Map<String,String> sendTo(Map<String,String> param){
        SendSmsResponse sendSmsResponse = new SendSmsResponse();

        String sms_code_start = param.get("sms_code_start");
        String sms_aliyun_accessKeyId = param.get("sms_aliyun_accessKeyId");
        String sms_aliyun_accessKeySecret =param.get("sms_aliyun_accessKeySecret");
        String sms_aliyun_signName = param.get("sms_aliyun_signName");
        String sms_aliyun_templateCode =param.get("sms_aliyun_templateCode");

        String mobile =param.get("mobile");
        String codeNo =param.get("codeNo");

        log.info("sms_aliyun_start->"+sms_code_start+"["+("F".equals(sms_code_start)?"已停用":"启用中")+"]");
        log.info("send sms mobile->"+mobile);
        log.info("send sms code->"+codeNo);
        if("F".equals(sms_code_start)){
            log.info("stop sms code push to aliyun platform !");
            return getResultMap("",codeNo,"OK","当前已停用发送验证码至aliyun平台，因此临时模拟发送！");
        }
        log.info("start sms code push to aliyun platform ...");
        log.info("sms_aliyun_accessKeyId->"+sms_aliyun_accessKeyId);
        log.info("sms_aliyun_accessKeySecret->"+sms_aliyun_accessKeySecret);
        log.info("sms_aliyun_signName->"+sms_aliyun_signName);
        log.info("sms_aliyun_templateCode->"+sms_aliyun_templateCode);
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        try {
            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", sms_aliyun_accessKeyId, sms_aliyun_accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号
            request.setPhoneNumbers(mobile);//18637357642
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(sms_aliyun_signName);
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(sms_aliyun_templateCode);
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.setTemplateParam("{\"code\":"+codeNo+"}");
            //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
            //request.setSmsUpExtendCode("90997");
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
//        request.setOutId("yourOutId");
            //hint 此处可能会抛出异常，注意catch
            sendSmsResponse = acsClient.getAcsResponse(request);
            log.info("aliyun platform response->"+JSONObject.fromObject(sendSmsResponse));
            return getResultMap(sendSmsResponse.getRequestId(),sendSmsResponse.getBizId(),sendSmsResponse.getCode(),sendSmsResponse.getMessage());
        } catch (ClientException e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return getResultMap("","","fail",e.getMessage());
        }
    }

    private static Map<String,String> getResultMap(String requestId,String bizId,String code,String message){
        Map<String,String> resultMap = new HashMap<String,String>();
        resultMap.put("requestId",requestId);
        resultMap.put("bizId",bizId);
        resultMap.put("code",code);
        resultMap.put("message",message);
        log.info("send sms return result->"+JSONObject.fromObject(resultMap));
        return resultMap;
    }

    public QuerySendDetailsResponse querySendDetails(String bizId,String mobile) throws ClientException {

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", this.sms_aliyun_accessKeyId, this.sms_aliyun_accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        //必填-号码
        request.setPhoneNumber(mobile);
        //可选-流水号
        request.setBizId(bizId);
        //必填-发送日期 支持30天内记录查询，格式yyyyMMdd
        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
        request.setSendDate(ft.format(new Date()));
        //必填-页大小
        request.setPageSize(10L);
        //必填-当前页码从1开始计数
        request.setCurrentPage(1L);

        //hint 此处可能会抛出异常，注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);

        return querySendDetailsResponse;
    }

    public static void main(String[] args) throws ClientException, InterruptedException {
        //发短信
        String mobile = "18511173289";
        String codeNo="666666";
        Map<String,String>  response = sendSms(mobile,codeNo);
        System.out.println("短信接口返回的数据----------------");
        System.out.println("Code=" + response);
        String code = response.get("code");
        String bizId = response.get("bizId");
        Thread.sleep(3000L);
        //查明细
        if(code != null && code.equals("OK")) {
            QuerySendDetailsResponse querySendDetailsResponse = new SmsUtil().querySendDetails(bizId,mobile);
            System.out.println("短信明细查询接口返回数据----------------");
            System.out.println("Code=" + querySendDetailsResponse.getCode());
            System.out.println("Message=" + querySendDetailsResponse.getMessage());
            int i = 0;
            for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs())
            {
                System.out.println("SmsSendDetailDTO["+i+"]:");
                System.out.println("Content=" + smsSendDetailDTO.getContent());
                System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
                System.out.println("OutId=" + smsSendDetailDTO.getOutId());
                System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
                System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
                System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
                System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
                System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
            }
            System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
            System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
        }

    }
}
